const jwt = require('jsonwebtoken');
const config = require('../config/config');
const db = require('../config/database');
const CustomError = require('../utils/error');
const errorTypes = require('../constants/error-types');

const verifyJwt = async (ctx, next) => {
  const authorization = ctx.request.headers.authorization || '';
  const token = authorization.replace('Bearer ', '');
  const error = new CustomError(errorTypes.TOKEN_UNVALIDATE);
  if (!token) {
    return ctx.app.emit('error', error, ctx);
  }
  const user = jwt.verify(token, config.APP_PUBLIC_KEY, {
    algorithms: ['RS256'],
  });
  if (!user) {
    return ctx.app.emit('error', error, ctx);
  }
  ctx.user = user;
  await next();
};

const verifyPermission = (tableName) => {
  return async (ctx, next) => {
    const id = ctx.params.id || ctx.request.body.id || -1;
    const sql = `select * from ${tableName} where id = ?;`;
    const [result] = await db.execute(sql, [id]);
    if (!result || !result.length) {
      return ctx.app.emit(
        'error',
        new CustomError(errorTypes.INFO_NOTFOUND),
        ctx
      );
    }
    if (ctx.user.id != result[0].user_id) {
      return ctx.app.emit(
        'error',
        new CustomError(errorTypes.NO_PERMISSON),
        ctx
      );
    }
    await next();
  };
};

const validContent = async (ctx, next) => {
  const { content = '' } = ctx.request.body;
  if (!content.length) {
    const error = new CustomError(errorTypes.CONTENT_REQUIRED);
    return ctx.app.emit('error', error, ctx);
  }
  await next();
};

module.exports = {
  verifyJwt,
  verifyPermission,
  validContent,
};
